#NoTrayIcon

gosub, InitApp

Esc:: ExitApp

return

;------------------------- End of auto execute section -----------------------
#Include %A_ScriptDir%
#include color\HSV.ahk
#include canvas\Canvas.ahk

#include ui\ui.ahk

InitApp:
    #NoEnv
    SendMode Input
    SetWorkingDir %A_ScriptDir%
    #Persistent
    #SingleInstance
    CoordMode, Mouse, Window
    CoordMode, Pixel, Window
    SetWinDelay, -1

    Menu, Tray, Tip, Color Picker
    Menu, Tray, Icon, images\color_wheel.ico
    Menu, Tray, Click, 1
    Menu, Tray, NoStandard
    Menu, Tray, Add, Open, ShowWindow
    Menu, Tray, Default, Open

    OnExit("ExitFunc")

    Menu, Tray, Add
    Menu, Tray, Add, Exit, ExitApplication

    hHookMouse := DllCall("SetWindowsHookEx", "int", 14, "Uint", RegisterCallback("Mouse", "Fast"), "Uint", 0, "Uint", 0)

    ; Loading saved state
    numberOfSwatches := 8
    swatches := []
    IniRead, currentSwatch, save.ini, General, CurrentSwatch, 1
    IniRead, pickerMode, save.ini, General, PickerMode, "Hue"
    IniRead, trueColors, save.ini, General, TrueColors, 0
    loop %numberOfSwatches% {
        IniRead, H, save.ini, % "Swatch" . A_Index, H, 1
        IniRead, S, save.ini, % "Swatch" . A_Index, S, 0
        IniRead, V, save.ini, % "Swatch" . A_Index, V, 0
        IniRead, A, save.ini, % "Swatch" . A_Index, A, 1
        swatches.Push({H:H, S:S, V:V, A:A})
    }

    gosub, InitGui
return

ExitApplication:
ExitApp

ShowWindow:
    WinShow, ahk_id %PickerHwnd%
    WinActivate, ahk_id %PickerHwnd%
return

ToggleWindowVisibility() {
    global guiHidden
    global PickerHwnd
    if guiHidden {
        WinShow, ahk_id %PickerHwnd%
    } else {
        WinHide, ahk_id %PickerHwnd%
    }
    guiHidden := !guiHidden
    return
}

ExitFunc(ExitReason, ExitCode) {
    ; Unhook mouse
    DllCall("UnhookWindowsHookEx", "Uint", hHookMouse)
    ; Save state
    global numberOfSwatches
    global swatches
    global currentSwatch
    global pickerMode
    global trueColors
    IniWrite, %currentSwatch%, save.ini, General, CurrentSwatch
    IniWrite, %pickerMode%, save.ini, General, PickerMode
    IniWrite, %trueColors%, save.ini, General, TrueColors
    loop %numberOfSwatches% {
        H := swatches[A_Index].H
        S := swatches[A_Index].S
        V := swatches[A_Index].V
        A := swatches[A_Index].A
        IniWrite, %H%, save.ini, % "Swatch" . A_Index, H
        IniWrite, %S%, save.ini, % "Swatch" . A_Index, S
        IniWrite, %V%, save.ini, % "Swatch" . A_Index, V
        IniWrite, %A%, save.ini, % "Swatch" . A_Index, A
    }
    if ErrorLevel {
        MsgBox, There was an error writing the save.ini file
    }
    ; ExitApp not needed
}

PickColorUnderCursor() {
    MouseGetPos, MouseX, MouseY
    PixelGetColor, color, %MouseX%, %MouseY%
    R := (color & 0x0000ff) / 256
    G := ((color & 0x00ff00)>>8) / 256
    B := ((color & 0xff0000)>>16) / 256
    c := HSV_Convert2HSV(R, G, B)
    global swatches
    global currentSwatch
    swatches[currentSwatch].H := c.H
    swatches[currentSwatch].S := c.S
    swatches[currentSwatch].V := c.V
    Redraw()
}
GetColorHexCode(WithHash := false, WithAlpha := false) {
    global swatches
    global currentSwatch
    cRGB := HSV2RGB_Number(swatches[currentSwatch])
    if (WithAlpha) {
        Alpha := Round(swatches[currentSwatch].A*255)
        color := Format("{1:06x}{2:02x}", cRGB, Alpha)
    } else {
        color := Format("{:06x}", cRGB)
    }
    if (WithHash) {
        color := "#" . color
    }
    Return color
}
SelectSwatch(n) {
    global numberOfSwatches
    if (n is not Number or n < 1 or n > numberOfSwatches)
        throw Exception("INVALID_INPUT",-1,"Invalid swatch number: " . n)
    global currentSwatch
    currentSwatch := n
    Redraw()
}

;----------------------------------- Hotkeys ---------------------------------
; To set up hotkeys for the functions, chose a hotkey and call the appropriate function.
; Examples:

; Pause::
;    ToggleWindowVisibility()
;    return
; ^Ins::
;    SendColorHexCode(true)
;    return
